package com.jaxb.binder;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;



/**
 * Abstract template class for BtStoneBinder.
 * @author yyjiangc
 * @version 1.0 03/07/2011
 */
public abstract class AbstractStoneBinder implements BtStoneBinder {
	
	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T unmarshall(String xml, Class<?> objFactoryClass)
			throws BindingException {
		try {
			Unmarshaller unmarshaller = createUnmarshaller(objFactoryClass);
			Object value = unmarshaller.unmarshal(new StringReader(xml));
			if (value instanceof JAXBElement) {
	            value = ((JAXBElement<?>) value).getValue();
	        }
			return (T) value;
		} catch (JAXBException e) {
			String msg = "Unmarshal error.";
			throw new BindingException(msg, e);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String marshall(JAXBElement<?> element, Class<?> objFactoryClass) throws BindingException {
		StringWriter sw = new StringWriter();	
		try {
			Marshaller marshaller = createMarshaller(objFactoryClass);
			
			marshaller.marshal(element, sw);
			return sw.toString();
		} catch (JAXBException e) {
			String msg = "Marshal error.";
			throw new BindingException(msg, e);
		}	
	}
	
	/**
	 * Create a Unmarshaller object.
	 * 
	 * @param objFactoryClass the ObjectFactory class object
	 * @return the Unmarshaller object created
	 * @throws JAXBException throws Exception if error occurs when create Unmarshaller. 
	 */
	protected abstract Unmarshaller createUnmarshaller(Class<?> objFactoryClass) 
	    throws JAXBException;
	
	/**
	 * Create a Marshaller object.
	 * 
	 * @param objFactoryClass the ObjectFactory class object
	 * @return the Marshaller object created
	 * @throws JAXBException throws Exception if error occurs when create Marshaller.
	 */
	protected abstract Marshaller createMarshaller(Class<?> objFactoryClass) 
        throws JAXBException;

}
